import random

lcase_chars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

hex_chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',]

# 62 characters -- plenty for uniqueness
alphanum_chars = [
    'a','b','c','d','e','f','g','h','i','j','k','l','m',
    'n','o','p','q','r','s','t','u','v','w','x','y','z',
    'A','B','C','D','E','F','G','H','I','J','K','L','M',
    'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
    '0','1','2','3','4','5','6','7','8','9']

# removing characters that might cause confusion, 54 remain
id_chars = [i for i in alphanum_chars 
            if i not in ['i','o','l','I','O','L','0','1']]
    
punct_chars = [
    '~','!','@','#','$','%','^','&','*','(',')','_','-','+',
    '=','[','{',']','}','|',';',':',',','<','.','>','/','?']

ascii_chars = alphanum_chars + punct_chars

# 73 characters long
urlslug_punct = [
    '$', '-', '_', '.', '+', '!', '*', "'", '(', ')', ',']
urlslug_chars = alphanum_chars + urlslug_punct

# 73^4 = 28.4 million unique URL slugs. 
# So a private URL shortener can be like the following:
#   www.tld.to/YpH0
# which exactly fits the size for micro-QR codes (15 characters).
# (This is exactly the size of links from www.goo.gl )

# 62^6 = 5.68e10, which is the length of a bit.ly id 
# (56.8 billion unique URLs).
# 62^32 = 2.27e57, which is overkill by a lot.
# 62^16 = 4.77e28, which is still huge 
# -- we'll never get a repeat, and we can test for it.

def random_id(length=16, charset=alphanum_chars, firstcharset=lcase_chars):
    """Creates a random id with the given length and charset. 
       Useful for surrogate keys, random passwords, session keys.
    """
    t = []  # build in a list, join at the end -- more efficient than repeated string ops.
    firstchars = list(set(charset).intersection(firstcharset))
    if len(firstchars)==0: firstchars = charset
    t.append(firstchars[int(random.random()*len(firstchars))])
    for i in range(0,length-1):                                 # iterate over the given length
        t.append(charset[int(random.random()*len(charset))])  # get a random character from the charset
    return ''.join(t)
